package com.bringspring.visualdev.generater.util.functionForm;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.bringspring.common.base.UserInfo;
import com.bringspring.common.config.ConfigValueUtil;
import com.bringspring.common.constant.MsgCode;
import com.bringspring.common.database.model.entity.DbLinkEntity;
import com.bringspring.common.database.model.DataSourceModel;
import com.bringspring.common.model.FormAllModel;
import com.bringspring.common.model.FormColumnModel;
import com.bringspring.common.model.FormColumnTableModel;
import com.bringspring.common.model.FormEnum;
import com.bringspring.common.model.visiual.*;
import com.bringspring.common.model.visiual.fields.FieLdsModel;
import com.bringspring.common.model.visiual.fields.config.ConfigModel;
import com.bringspring.common.model.visiual.fields.props.PropsBeanModel;
import com.bringspring.common.model.visiual.fields.props.PropsModel;
import com.bringspring.common.model.visiual.fields.slot.SlotModel;
import com.bringspring.common.util.DateUtil;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.XSSEscape;
import com.bringspring.system.base.util.SourceUtil;
import com.bringspring.visualdev.base.entity.VisualdevEntity;
import com.bringspring.visualdev.base.model.template6.AuthorityModel;
import com.bringspring.visualdev.base.model.template6.BtnData;
import com.bringspring.visualdev.base.model.template7.Template7Model;
import com.bringspring.visualdev.base.util.VisualUtils;
import com.bringspring.visualdev.generater.model.FormDesign.ColumnListDataModel;
import com.bringspring.visualdev.generater.model.FormDesign.ColumnListModel;
import com.bringspring.visualdev.generater.model.FormDesign.ListSearchGroupModel;
import com.bringspring.visualdev.generater.model.GenBaseInfo;
import com.bringspring.visualdev.generater.model.GenFileNameSuffix;
import com.bringspring.visualdev.generater.model.SearchTypeModel;
import com.bringspring.visualdev.generater.util.common.CodeGenerateUtil;
import com.bringspring.visualdev.generater.util.common.DataControlUtils;
import com.bringspring.visualdev.generater.util.common.FunctionFormPublicUtil;
import com.bringspring.visualdev.generater.util.custom.CustomGenerator;
import com.bringspring.workflow.engine.model.flowengine.FlowExportModel;
import com.google.common.base.CaseFormat;
import lombok.Cleanup;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 开发平台组
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2021/3/16
 */
public class FunctionFlowUtil implements CodeGenerateUtil {
	private static FunctionFlowUtil  functionFlowUtil = new FunctionFlowUtil();

	private FunctionFlowUtil(){

	}

	public static FunctionFlowUtil getFunctionFlowUtil (){
		return functionFlowUtil;
	}
	//------------------------------------界面----------------------------------

	/**
	 * 界面模板
	 *
	 * @param fileName         文件夹名称
	 * @param downloadCodeForm 文件名称
	 * @param model            模型
	 * @param templatePath     模板路径
	 * @param userInfo         用户
	 * @param configValueUtil  下载路径
	 */
	@Override
	public  void htmlTemplates(String fileName, VisualdevEntity entity, DownloadCodeForm downloadCodeForm,
							   FormDataModel model, String templatePath, UserInfo userInfo,
							   ConfigValueUtil configValueUtil, String pKeyName) throws Exception{
		Map<String, Object> map = new HashMap<>(16);
		//formTempJson
		FormDataModel formData = JsonUtil.getJsonToBean(entity.getFormData(), FormDataModel.class);
		List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
		ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(entity.getColumnData(), ColumnDataModel.class);
		List<ColumnListField> columnList = JsonUtil.getJsonToList(columnDataModel.getColumnList(), ColumnListField.class);
		List<FormAllModel> formAllModel = new ArrayList<>();
		RecursionForm recursionForm = new RecursionForm();
		recursionForm.setTableModelList(JsonUtil.getJsonToList(entity.getVisualTables(), TableModel.class));
		recursionForm.setList(list);
		FormCloumnUtil.recursionForm(recursionForm, formAllModel);

		//form的属性
		List<FormAllModel> mast = formAllModel.stream().filter(t -> FormEnum.mast.getMessage().equals(t.getKeyName())).collect(Collectors.toList());
		List<FormAllModel> table = formAllModel.stream().filter(t -> FormEnum.table.getMessage().equals(t.getKeyName())).collect(Collectors.toList());
		List<FormAllModel> mastTable = formAllModel.stream().filter(t-> FormEnum.mastTable.getMessage().equals(t.getKeyName())).collect(Collectors.toList());

		List<FieLdsModel> allColumnFiledModelList = new ArrayList<>();
		allColumnFiledModelList.addAll(mast.stream().map(ma -> ma.getFormColumnModel().getFieLdsModel()).collect(Collectors.toList()));
		allColumnFiledModelList.addAll(mastTable.stream().map(mt->mt.getFormMastTableModel().getMastTable().getFieLdsModel()).collect(Collectors.toList()));
		//columnTempJson
		Map<String, Object> columnDataMap = JsonUtil.stringToMap(entity.getColumnData());

		List<TableModel> tablesList = JsonUtil.getJsonToList(entity.getVisualTables(), TableModel.class);
		//列表字段
		List<ColumnListModel> columnListModelList = JsonUtil.getJsonToList(columnDataModel.getColumnList(), ColumnListModel.class);

		//取对应表的别名
		Map<String, String> tableNameRenames = FunctionFormPublicUtil.tableNameRename(downloadCodeForm, tablesList);

		columnListModelList.stream().map(c->{
			FieLdsModel fieLdsModel = allColumnFiledModelList.stream().filter(f -> f.getVModel().equals(c.getProp())).findFirst().orElse(null);
			if(fieLdsModel!=null) {
				c.setKeyName(fieLdsModel.getConfig().getKeyName());
				c.setDataType(fieLdsModel.getConfig().getDataType());
				c.setVModel(fieLdsModel.getVModel());
			}
			return c;
		}).collect(Collectors.toList());

		//列表中区别子表正则
		String reg = "^[jsbos_]\\S*_jsbos\\S*";
		columnListModelList.stream().filter(c-> c.getVModel().matches(reg)).forEach(
				cl->{
					String s = cl.getVModel();
					String s1 = s.substring(s.lastIndexOf("jsbos_")).replace("jsbos_","");
					String s2 = s.substring(s.indexOf("_")+1, s.lastIndexOf("_jsbos"));
					cl.setNewProp(s2.toLowerCase()+"."+s1);
					cl.setColumnTableName(s2);
				}
		);

		List<FieLdsModel> searchList = JsonUtil.getJsonToList(columnDataMap.get("searchList"), FieLdsModel.class);
		//查询条件
		List<SearchTypeModel> searchTypeModelList =new ArrayList<>();
		searchList.stream().forEach(fieLdsModel ->{
			SearchTypeModel searchTypeModel = new SearchTypeModel();
			searchTypeModel.setSearchType(fieLdsModel.getSearchType());
			searchTypeModel.setVModel(fieLdsModel.getVModel());
			searchTypeModel.setLabel(fieLdsModel.getConfig().getLabel());
			searchTypeModel.setFormat(fieLdsModel.getFormat());
			searchTypeModel.setKeyName(fieLdsModel.getConfig().getKeyName());
			String placeholder = fieLdsModel.getSearchType().equals(3) ?  fieLdsModel.getPlaceholder() : DataControlUtils.getPlaceholder(fieLdsModel.getConfig().getKeyName());
			searchTypeModel.setPlaceholder(placeholder);
			searchTypeModel.setConfig(fieLdsModel.getConfig());
			searchTypeModel.setShowLevel(fieLdsModel.getShowLevel());
			searchTypeModelList.add(searchTypeModel);
		});

		if (searchTypeModelList.size()>0){
			for (TableFields tableFields : tablesList.get(0).getFields()){
				searchTypeModelList.stream().forEach(searchTypeModel -> {
					if (searchTypeModel.getVModel().equals(tableFields.getField())){
						searchTypeModel.setDataType(tableFields.getDataType());
					}
				});
			}
		}


		//表单子表模型
		List<ColumnListDataModel> formChildList = new ArrayList<>();

		//form和model
		Template7Model temModel = new Template7Model();
		temModel.setServiceDirectory(configValueUtil.getServiceDirectoryPath());
		temModel.setCreateDate(DateUtil.daFormat(new Date()));
		temModel.setCreateUser(GenBaseInfo.AUTHOR);
		temModel.setCopyright(GenBaseInfo.COPYRIGHT);

		//temModel.setClassName(DataControlUtils.captureName(downloadCodeForm.getClassName()));
		temModel.setClassName(NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(downloadCodeForm.getClassName())));
		temModel.setDescription("");
		map.put("genInfo", temModel);
		map.put("modelName", model.getClassName());
		map.put("package", GenBaseInfo.PACKAGE_NAME);

		//子表赋值
		List<Map<String, Object>> child = new ArrayList<>();
		for (int i = 0; i < table.size(); i++) {
			FormColumnTableModel childList = table.get(i).getChildList();
			List<FormColumnModel> tableList = childList.getChildList();
			for (FormColumnModel columnModel : tableList) {
				FieLdsModel fieLdsModel = columnModel.getFieLdsModel();
				SlotModel slot = fieLdsModel.getSlot();
				if (slot != null) {
					slot.setAppOptions(slot.getOptions());
					fieLdsModel.setSlot(slot);
				}
			}
			childList.setChildList(tableList);
			Map<String, Object> childs = JsonUtil.entityToMap(childList);
			String className = NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(downloadCodeForm.getClassName()));
			childs.put("className", className);
			child.add(childs);
		}
		//主表赋值
		for (int i = 0; i < mast.size(); i++) {
			FieLdsModel fieLdsModel = mast.get(i).getFormColumnModel().getFieLdsModel();
			ConfigModel configModel = fieLdsModel.getConfig();
			if(ObjectUtil.isNotEmpty(fieLdsModel.getProps())){
				if (StringUtils.isNotEmpty(fieLdsModel.getProps().getProps())){
					PropsBeanModel propsBeanModel = JsonUtil.getJsonToBean(fieLdsModel.getProps().getProps(), PropsBeanModel.class);
					fieLdsModel.getProps().setPropsModel(propsBeanModel);
				}
			}
			if (configModel.getDefaultValue() instanceof String) {
				configModel.setValueType("String");
			}
			if (configModel.getDefaultValue() == null) {
				configModel.setValueType("undefined");
			}
			fieLdsModel.setConfig(configModel);
			SlotModel slot = fieLdsModel.getSlot();
			String vmodel = fieLdsModel.getVModel();
			if (slot != null) {
				slot.setAppOptions(slot.getOptions());
				fieLdsModel.setSlot(slot);
			}
			if (StringUtils.isEmpty(vmodel)) {
				mast.remove(i);
			}
		}

		for (int i = 0; i < mastTable.size(); i++) {
			FieLdsModel fieLdsModel = mastTable.get(i).getFormMastTableModel().getMastTable().getFieLdsModel();
			if(ObjectUtil.isNotEmpty(fieLdsModel.getProps())){
				if (StringUtils.isNotEmpty(fieLdsModel.getProps().getProps())){
					PropsBeanModel propsBeanModel = JsonUtil.getJsonToBean(fieLdsModel.getProps().getProps(), PropsBeanModel.class);
					fieLdsModel.getProps().setPropsModel(propsBeanModel);
				}
			}
		}

		//列表子表数据model
		Map<String, List<FormAllModel>> groupColumnDataMap = mastTable.stream().collect(Collectors.groupingBy(m -> m.getFormMastTableModel().getTable()));
		Iterator<Map.Entry<String,List<FormAllModel>>> entries = groupColumnDataMap.entrySet().iterator();
		while (entries.hasNext()){
			Map.Entry<String, List<FormAllModel>> formEntries = entries.next();
			Map<String, Object> objectMap = new HashMap<>();
			String className = NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(tableNameRenames.get(formEntries.getKey())));
			ColumnListDataModel columnListDataModel =new ColumnListDataModel();
			columnListDataModel.setModelName(className);
			columnListDataModel.setModelUpName(className);
			columnListDataModel.setModelLowName(DataControlUtils.initialLowercase(className));
			List<FormAllModel> allModels = formEntries.getValue();
			allModels.stream().forEach(m->{
				String vModel = m.getFormMastTableModel().getField();
				m.getFormMastTableModel().getMastTable().getFieLdsModel().setVModel(vModel);
			});
			List<String> fields = allModels.stream().map(m ->
					m.getFormMastTableModel().getField()).collect(Collectors.toList());
			columnListDataModel.setFieldList(fields);
			columnListDataModel.setFieLdsModelList(allModels.stream().map(al->al.getFormMastTableModel()).collect(Collectors.toList()));
			columnListDataModel.setTableName(formEntries.getKey());
			formChildList.add(columnListDataModel);
			List<FormColumnModel> children = formEntries.getValue().stream().map(allModel -> allModel.getFormMastTableModel().getMastTable()).collect(Collectors.toList());

			FormColumnTableModel formColumnTableModel = new FormColumnTableModel();
			formColumnTableModel.setChildList(children);
			objectMap.put("children", formColumnTableModel);
			objectMap.put("genInfo", temModel);
			objectMap.put("package", GenBaseInfo.PACKAGE_NAME);
			objectMap.put("module", model.getAreasName());
			objectMap.put("className", className);
			childrenTemplates(model.getServiceDirectory() + fileName, objectMap, templatePath, className, downloadCodeForm.getClassName(),true);
		}

		//子表model
		for (int i = 0; i < table.size(); i++) {
			FormColumnTableModel childList = table.get(i).getChildList();
			Map<String, Object> objectMap = JsonUtil.entityToMap(childList);
			String className = NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(tableNameRenames.get(childList.getTableName())));
			objectMap.put("children", childList);
			objectMap.put("genInfo", temModel);
			objectMap.put("package", GenBaseInfo.PACKAGE_NAME);
			objectMap.put("module", model.getAreasName());
			objectMap.put("className", className);
			childrenTemplates(model.getServiceDirectory() + fileName, objectMap, templatePath, className, downloadCodeForm.getClassName(),false);
		}

		mast.stream().forEach(ms->{
			PropsModel propsModel = ms.getFormColumnModel().getFieLdsModel().getProps();
			if (ObjectUtil.isNotEmpty(propsModel)){
				String props = propsModel.getProps();
				propsModel.setPropsModel(JsonUtil.getJsonToBean(props, PropsBeanModel.class));
			}
		});

		//界面
		map.put("module", downloadCodeForm.getModule());
		map.put("className",DataControlUtils.captureName(model.getClassName()));
		map.put("formRef", model.getFormRef());
		map.put("formModel", model.getFormModel());
		map.put("size", model.getSize());
		map.put("labelPosition", model.getLabelPosition());
		map.put("generalWidth",model.getGeneralWidth());
		map.put("formStyle",model.getFormStyle());
		map.put("labelWidth", model.getLabelWidth());
		map.put("formRules", model.getFormRules());
		map.put("gutter", model.getGutter());
		map.put("disabled", model.getDisabled());
		map.put("span", model.getSpan());
		map.put("formBtns", model.getFormBtns());
		map.put("idGlobal", model.getIdGlobal());
		map.put("popupType", model.getPopupType());
		map.put("form", formAllModel);
		map.put("columnData", columnDataMap);
		map.put("columnDataListFiled",columnListModelList);
		map.put("flowId",entity.getFlowId());
		map.put("searchTypeList",searchTypeModelList);
		map.put("searchList",searchList);
		map.put("enCode",entity.getEnCode());


		//共用
		map.put("children", child);
		map.put("mastTable",mastTable);
		map.put("fields", mast);
		map.put("columnChildren",formChildList);
		pKeyName = pKeyName.toLowerCase().trim().replaceAll("f_", "");
		map.put("pKeyName", pKeyName);
		map.put("columnList",columnList);
		String modelPathName = downloadCodeForm.getClassName().toLowerCase();
		map.put("modelPathName",modelPathName);
		map.put("isMain",true);
		htmlTemplates(model.getServiceDirectory() + fileName, map, templatePath);

		String path = configValueUtil.getServiceDirectoryPath() + File.separator + fileName;
		FlowExportModel exportModel = FunctionFormPublicUtil.jsonFile(entity, downloadCodeForm);
		FunctionFormPublicUtil.createFile(JsonUtil.getObjectToString(exportModel),path);

	}

	/**
	 * 获取文件名
	 *
	 * @param path      路径
	 * @param template  模板名称
	 * @param className 文件名称
	 * @return
	 */
	private static String getFileName(String path, String template, String className) {
		String modelPath = XSSEscape.escapePath(path + File.separator + "java" + File.separator + "model" + File.separator + className.toLowerCase());
		String htmlPath = XSSEscape.escapePath(path + File.separator + "html" + File.separator + "web"+ File.separator + className.toLowerCase());
		File htmlfile = new File(htmlPath);
		File modelfile = new File(modelPath);
		if (!htmlfile.exists()) {
			htmlfile.mkdirs();
		}
		if (!modelfile.exists()) {
			modelfile.mkdirs();
		}
		if (template.contains("form.vue.vm")) {
			className = "form";
			return htmlPath + File.separator + className + ".vue";
		}
		if (template.contains("index.vue.vm")) {
			className = "index";
			return htmlPath + File.separator + className + ".vue";
		}
		if (template.contains("ExportBox.vue.vm")) {
			className = "ExportBox";
			return htmlPath + File.separator + className + ".vue";
		}
		if (template.contains("InfoVO.java.vm")) {
			return modelPath + File.separator + className + "InfoVO.java";
		}
		if (template.contains("CrForm.java.vm")) {
			return modelPath + File.separator + className + "CrForm.java";
		}
		if (template.contains("ListQuery.java.vm")) {
			return modelPath + File.separator + className + "ListQuery.java";
		}
		if (template.contains("ListVO.java.vm")) {
			return modelPath + File.separator + className + "ListVO.java";
		}
		if (template.contains("Pagination.java.vm")) {
			return modelPath + File.separator + className + "Pagination.java";
		}
		if (template.contains("PaginationExportModel.java.vm")) {
			return modelPath + File.separator + className + "PaginationExportModel.java";
		}
		if (template.contains("UpForm.java.vm")) {
			return modelPath + File.separator + className + "UpForm.java";
		}
		return null;
	}

	/**
	 * 界面的模板
	 *
	 * @param template 模板集合
	 * @return
	 */
	private static List<String> getTemplates(String template) {
		List<String> templates = new ArrayList<>();
		templates.add(template + File.separator + "html" + File.separator + "index.vue.vm");
		templates.add(template + File.separator + "html" + File.separator + "form.vue.vm");
		templates.add(template + File.separator + "html" + File.separator + "ExportBox.vue.vm");
		templates.add(template + File.separator + "java" + File.separator + "InfoVO.java.vm");
		templates.add(template + File.separator + "java" + File.separator + "CrForm.java.vm");
		templates.add(template + File.separator + "java" + File.separator + "ListQuery.java.vm");
		templates.add(template + File.separator + "java" + File.separator + "ListVO.java.vm");
		templates.add(template + File.separator + "java" + File.separator + "Pagination.java.vm");
		templates.add(template + File.separator + "java" + File.separator + "PaginationExportModel.java.vm");
		templates.add(template + File.separator + "java" + File.separator + "UpForm.java.vm");
		return templates;
	}

	/**
	 * 渲染html模板
	 *
	 * @param path         路径
	 * @param object       模板数据
	 * @param templatePath 模板路径
	 */
	private static void htmlTemplates(String path, Map<String, Object> object, String templatePath) throws Exception{
		List<String> templates = getTemplates(templatePath);
		//界面模板
		VelocityContext context = new VelocityContext();
		context.put("context", object);
		for (String template : templates) {
			try {
				// 渲染模板
				@Cleanup StringWriter sw = new StringWriter();
				Template tpl = Velocity.getTemplate(template, Constants.UTF_8);
				tpl.merge(context, sw);
				String className = object.get("className").toString();
				String fileNames = getFileName(path, template, className);
				if (fileNames != null) {
					File file = new File(XSSEscape.escapePath(fileNames));
					if (!file.exists()) {
						file.createNewFile();
					}
					@Cleanup FileOutputStream fos = new FileOutputStream(file);
					IOUtils.write(sw.toString(), fos, Constants.UTF_8);
					IOUtils.closeQuietly(sw);
					IOUtils.closeQuietly(fos);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static String getChildrenFileName(String dirNames,String template,String className){
		String finallyPath ="";
		if (template.contains("Model.java.vm")) {
			finallyPath=dirNames + File.separator + className + "Model.java";
		}else if (template.contains("ListVO.java.vm")){
			finallyPath=dirNames + File.separator + className + "ListVO.java";
		}
		return finallyPath;
	}

	/**
	 * 渲染html模板
	 *
	 * @param path         路径
	 * @param object       模板数据
	 * @param templatePath 模板路径
	 */
	private static void childrenTemplates(String path, Map<String, Object> object, String templatePath, String className, String model,Boolean isChild) {
		List<String> templates = new ArrayList<>();
		templates.add(templatePath + File.separator + "java" + File.separator + "Model.java.vm");
		if (isChild){
			templates.add(templatePath + File.separator + "java" + File.separator + "ListVO.java.vm");
		}
		//界面模板
		VelocityContext context = new VelocityContext();
		context.put("context", object);
		for (String template : templates) {
			try {
				// 渲染模板
				@Cleanup StringWriter sw = new StringWriter();
				Template tpl = Velocity.getTemplate(template, Constants.UTF_8);
				tpl.merge(context, sw);
				String dirNames = path + File.separator + "java" + File.separator + "model" + File.separator + model.toLowerCase();
				String fileNames=getChildrenFileName(dirNames,template,className);
				if (fileNames != null) {
					File file = new File(XSSEscape.escapePath(fileNames));
					if (!file.exists()) {
						File dirFile = new File(XSSEscape.escapePath(dirNames));
						if (!dirFile.exists()) {
							dirFile.mkdirs();
						}
						file.createNewFile();
					}
					@Cleanup FileOutputStream fos = new FileOutputStream(file);
					IOUtils.write(sw.toString(), fos, Constants.UTF_8);
					IOUtils.closeQuietly(sw);
					IOUtils.closeQuietly(fos);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	//-------------------------代码----------------------------------

	/**
	 * 生成主表
	 *
	 * @param path             路径
	 * @param fileName         文件夹名称
	 * @param downloadCodeForm 文件名称
	 * @param entity           实体
	 * @param userInfo         用户
	 * @param configValueUtil  下载路径
	 */
	private static void setCode(String path, String fileName, String templatePath, DownloadCodeForm downloadCodeForm, VisualdevEntity entity, UserInfo userInfo, ConfigValueUtil configValueUtil, DbLinkEntity linkEntity) throws SQLException {
		@Cleanup Connection conn = VisualUtils.getDataConn(linkEntity);
		//tableJson
		List<TableModel> tableModelList = JsonUtil.getJsonToList(entity.getVisualTables(), TableModel.class);
		//主表
		TableModel mainTable = tableModelList.stream().filter(t -> t.getTypeId().equals("1")).findFirst().orElse(null);

		//获取主表主键
		String pKeyName = VisualUtils.getpKey(conn, mainTable.getTable()).toLowerCase().trim().replaceAll("f_", "");

		//赋值主键
		tableModelList.stream().forEach(t-> {
			try {
				t.setTableKey(VisualUtils.getpKey(conn,t.getTable()));
			} catch (SQLException sqlException) {
				sqlException.printStackTrace();
			}
		});
		Map<String, Object> columndata = new HashMap<>(16);
		Template7Model model = new Template7Model();
		model.setClassName(NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(downloadCodeForm.getClassName())));
		model.setServiceDirectory(configValueUtil.getServiceDirectoryPath());
		model.setCreateDate(DateUtil.daFormat(new Date()));
		model.setCreateUser(GenBaseInfo.AUTHOR);
		model.setCopyright(GenBaseInfo.COPYRIGHT);
		model.setDescription(downloadCodeForm.getDescription());

		//columnTempJson
		ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(entity.getColumnData(),ColumnDataModel.class);
		//app 列表对象
		ColumnDataModel appColumnDataModel = JsonUtil.getJsonToBean(entity.getAppColumnData(), ColumnDataModel.class);

		//按钮
		List<BtnData> btnDataList = JsonUtil.getJsonToList(columnDataModel.getBtnsList(),BtnData.class);
		List<BtnData> columnBtnDataList = JsonUtil.getJsonToList(columnDataModel.getColumnBtnsList(), BtnData.class);

		List<ColumnListField> columnList = JsonUtil.getJsonToList(columnDataModel.getColumnList(), ColumnListField.class);
		List<FieLdsModel> searchList = JsonUtil.getJsonToList(columnDataModel.getSearchList(), FieLdsModel.class);

		//权限
		AuthorityModel authority= new AuthorityModel();
		BeanUtil.copyProperties(columnDataModel,authority);

		//取对应表的别名
		Map<String, String> tableNameRenames = FunctionFormPublicUtil.tableNameRename(downloadCodeForm, tableModelList);

		//子表集合
		List<TableModel> childTableNameList = new ArrayList<>();
		//全部表
		List<TableModel> allTableNameList = new ArrayList<>();

		for (TableModel tableModel : tableModelList){
			TableModel Model =new TableModel();
			//Model.setTable(tableNameRenames.get(tableModel.getTable()));
			Model.setTable(NamingStrategy.underlineToCamel(tableNameRenames.get(tableModel.getTable())));
			Model.setTableField(DataControlUtils.captureName(tableModel.getTableField()));
			allTableNameList.add(Model);
			if ("0".equals(tableModel.getTypeId())){
				childTableNameList.add(Model);
			}
		}

		//查询条件
		List<SearchTypeModel> searchTypeModelList =new ArrayList<>();
		searchList.stream().forEach(fieLdsModel ->{
			SearchTypeModel searchTypeModel = new SearchTypeModel();
			searchTypeModel.setSearchType(fieLdsModel.getSearchType());
			searchTypeModel.setVModel(fieLdsModel.getVModel());
			searchTypeModel.setLabel(fieLdsModel.getConfig().getLabel());
			searchTypeModel.setKeyName(fieLdsModel.getConfig().getKeyName());
			searchTypeModel.setFormat(fieLdsModel.getFormat());
			searchTypeModel.setMultiple(String.valueOf(fieLdsModel.getMultiple()));
			searchTypeModelList.add(searchTypeModel);
		});
		List<ListSearchGroupModel> groupModels =new ArrayList<>();
		if (searchTypeModelList.size()>0){
			//主表
			for (TableFields tableFields : tableModelList.get(0).getFields()){
				searchTypeModelList.stream().forEach(searchTypeModel -> {
					if (searchTypeModel.getVModel().equals(tableFields.getField())){
						searchTypeModel.setDataType(tableFields.getDataType());
					}
				});
			}
			//鉴别列表子表正则
			String reg = "^[jsbos_]\\S*_jsbos\\S*";
			searchTypeModelList.stream().filter(s->s.getVModel().matches(reg)).forEach(cl->{
						String s = cl.getVModel();
						String s1 = s.substring(s.lastIndexOf("jsbos_")).replace("jsbos_","");
						String s2 = s.substring(s.indexOf("_")+1, s.lastIndexOf("_jsbos"));
						cl.setAfterVModel(s1);
						cl.setTableName(s2);
						TableModel tableModel = tableModelList.stream().filter(t -> t.getTable().equalsIgnoreCase(s2)).findFirst().orElse(null);
						cl.setDataType(tableModel.getFields().stream().filter(t->t.getField().equalsIgnoreCase(s1)).findFirst().orElse(null).getDataType());
					}
			);
			//逻辑查询条件
			Map<String, List<SearchTypeModel>> collect = searchTypeModelList.stream().filter(s -> s.getVModel().matches(reg)).collect(Collectors.groupingBy(t -> t.getTableName()));
			 groupModels = collect.entrySet().stream().map(c -> {
						ListSearchGroupModel groupModel = new ListSearchGroupModel();
						groupModel.setModelName(tableNameRenames.get(c.getKey()));
						groupModel.setTableName(c.getKey());
						TableModel tableModel = tableModelList.stream().filter(t -> t.getTable().equalsIgnoreCase(c.getKey())).findFirst().orElse(null);
						groupModel.setForeignKey(tableModel.getTableField());
						groupModel.setMainKey(tableModel.getRelationField());
				 		groupModel.setSearchTypeModelList(c.getValue());
						return groupModel;
					}
			).collect(Collectors.toList());
			ListSearchGroupModel groupModel = new ListSearchGroupModel();
			groupModel.setSearchTypeModelList(searchTypeModelList.stream().filter(s->!s.getVModel().matches(reg)).collect(Collectors.toList()));
			groupModel.setTableName(NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(mainTable.getTable())));
			groupModel.setModelName(NamingStrategy.underlineToCamel(tableNameRenames.get(mainTable.getTable())));

			groupModels.add(groupModel);
		}

		//formTempJson
		FormDataModel formData = JsonUtil.getJsonToBean(entity.getFormData(), FormDataModel.class);
		List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
		List<FormAllModel> formAllModel = new ArrayList<>();
		RecursionForm recursionForm = new RecursionForm();
		recursionForm.setTableModelList(JsonUtil.getJsonToList(entity.getVisualTables(), TableModel.class));
		recursionForm.setList(list);
		FormCloumnUtil.recursionForm(recursionForm, formAllModel);
		//主表数据
		List<FormAllModel> mast = formAllModel.stream().filter(t -> FormEnum.mast.getMessage().equals(t.getKeyName())).collect(Collectors.toList());
		List<FormAllModel> table = formAllModel.stream().filter(t -> FormEnum.table.getMessage().equals(t.getKeyName())).collect(Collectors.toList());
		//列表子表数据
		List<FormAllModel> mastTable = formAllModel.stream().filter(t -> FormEnum.mastTable.getMessage().equals(t.getKeyName())).collect(Collectors.toList());

		//表单子表模型
		List<ColumnListDataModel> formChildList = new ArrayList<>();

		//列表子表数据model
		Map<String, List<FormAllModel>> groupColumnDataMap = mastTable.stream().collect(Collectors.groupingBy(m -> m.getFormMastTableModel().getTable()));
		Iterator<Map.Entry<String,List<FormAllModel>>> entries = groupColumnDataMap.entrySet().iterator();
		while (entries.hasNext()) {
			Map.Entry<String, List<FormAllModel>> formEntries = entries.next();
			String className = DataControlUtils.captureName(tableNameRenames.get(formEntries.getKey()));
			ColumnListDataModel columnListDataModel =new ColumnListDataModel();
			columnListDataModel.setModelName(className);
			columnListDataModel.setModelUpName(DataControlUtils.captureName(className));
			columnListDataModel.setModelLowName(DataControlUtils.initialLowercase(className));
			List<FormAllModel> allModels = formEntries.getValue();
			List<String> fields = allModels.stream().map(m ->
				 m.getFormMastTableModel().getField()).collect(Collectors.toList());
			columnListDataModel.setFieldList(fields);
			columnListDataModel.setFieLdsModelList(allModels.stream().map(al->al.getFormMastTableModel()).collect(Collectors.toList()));
			columnListDataModel.setTableName(formEntries.getKey());

			List<FieLdsModel> collect = allModels.stream().map(all -> all.getFormMastTableModel().getMastTable().getFieLdsModel()).collect(Collectors.toList());
			collect.stream().forEach(c->{
				PropsModel propsModel = c.getProps();
				if (propsModel != null) {
					PropsBeanModel props = JsonUtil.getJsonToBean(propsModel.getProps(), PropsBeanModel.class);
					propsModel.setPropsModel(props);
				}
				String vmodel= c.getVModel().substring(c.getVModel().lastIndexOf("jsbos_")).replace("jsbos_","");
				c.setVModel(vmodel);
				c.setProps(propsModel);
			});
			columnListDataModel.setFieLdsModels(collect);
			formChildList.add(columnListDataModel);
		}
		formChildList.stream().forEach(f->{
			TableModel tableModel = tableModelList.stream().filter(t -> t.getTable().equalsIgnoreCase(f.getTableName())).findFirst().orElse(null);
			if (ObjectUtil.isNotEmpty(tableModel)){
				f.setMainKey(tableModel.getRelationField());
				f.setRelationField(tableModel.getTableField());
				f.setMainUpKey(DataControlUtils.captureName(tableModel.getRelationField()));
				f.setRelationUpField(DataControlUtils.captureName(tableModel.getTableField()));
				String tableKey = tableModel.getTableKey().toLowerCase().replace("f_","");
				f.setMainField(DataControlUtils.captureName(tableKey));
			}
		});

		//主表的字段
		Optional<TableModel> first = tableModelList.stream().filter(t -> "1".equals(t.getTypeId())).findFirst();
		if(!first.isPresent()){
			throw new SQLException(MsgCode.COD001.get());
		}
		String tableName = first.get().getTable();
		String billNo = "";
		List<FieLdsModel> system = new ArrayList<>();
		for (int i = 0; i < mast.size(); i++) {
			FormAllModel mastModel = mast.get(i);
			FieLdsModel fieLdsModel = mastModel.getFormColumnModel().getFieLdsModel();
			PropsModel propsModel = fieLdsModel.getProps();
			if (StringUtils.isNotEmpty(fieLdsModel.getVModel())) {
				if (propsModel != null) {
					PropsBeanModel props = JsonUtil.getJsonToBean(propsModel.getProps(), PropsBeanModel.class);
					propsModel.setPropsModel(props);
				}
				fieLdsModel.setProps(propsModel);
				system.add(fieLdsModel);
			}
		}


		//子表的属性
		List<Map<String, Object>> child = new ArrayList<>();
		for (int i = 0; i < table.size(); i++) {
			FormColumnTableModel childList = table.get(i).getChildList();
			String className = DataControlUtils.captureName(tableNameRenames.get(childList.getTableName()));
			Map<String, Object> childs = JsonUtil.entityToMap(childList);
			Optional<TableModel> first1 = tableModelList.stream().filter(t -> t.getTable().equals(childList.getTableName())).findFirst();
			if(!first1.isPresent()){
				throw new SQLException(MsgCode.COD001.get());
			}
			TableModel tableModel = first1.get();
			//获取主表主键
			String chidKeyName = VisualUtils.getpKey(conn, tableModel.getTable());
			String tableField = tableModel.getTableField().trim().replaceAll(":\"f_", ":\"");
			childs.put("tableField", tableField);
			String relationField = tableModel.getRelationField().trim().replaceAll(":\"f_", ":\"");
			childs.put("relationField", relationField);
			childs.put("className", className);
			String keyName = chidKeyName.trim().toLowerCase().replaceAll("f_", "");
			childs.put("chidKeyName", keyName);
			child.add(childs);
		}
		//后台
		columndata.put("module", downloadCodeForm.getModule());
		columndata.put("genInfo", model);
		columndata.put("modelName", model.getClassName());
		columndata.put("typeId", 1);
		columndata.put("system", system);
		columndata.put("child", child);
		columndata.put("billNo", billNo);
		columndata.put("pKeyName", pKeyName);
		columndata.put("fieldsSize",system.size());
		columndata.put("btnsList",btnDataList);
		columndata.put("searchList",searchList);
		columndata.put("columnList",columnList);
		columndata.put("hasPage", columnDataModel.getHasPage());
		columndata.put("VisualDevId",entity.getId());
		columndata.put("main",true);
		columndata.put("defaultSidx",columnDataModel.getDefaultSidx());
		columndata.put("sort",columnDataModel.getSort());
		columndata.put("searchTypeModelList",searchTypeModelList);
		columndata.put("columnBtnsList",columnBtnDataList);
		columndata.put("mast",mast);
		columndata.put("childtable",table);
		columndata.put("authority",authority);
		//app pc 数据权限是否开启
		columndata.put("pcDataPermisson",columnDataModel.getUseDataPermission());
		columndata.put("appDataPermisson",appColumnDataModel.getUseDataPermission());
		columndata.put("columnChildren",formChildList);
		columndata.put("groupModels",groupModels);
		columndata.put("childTableNameList",childTableNameList);
		columndata.put("allTableNameList",allTableNameList);
		if (ObjectUtil.isNotEmpty(linkEntity)){
			columndata.put("DS",linkEntity.getFullName());
		}
		CustomGenerator mpg = new CustomGenerator(columndata);
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setFileOverride(true);
		// 不需要ActiveRecord特性的请改为false
		gc.setActiveRecord(false);
		// XML 二级缓存
		gc.setEnableCache(false);
		// XML ResultMap
		gc.setBaseResultMap(false);
		// XML columList
		gc.setBaseColumnList(false);
		gc.setAuthor(userInfo.getRealName() + "/" + userInfo.getUserAccount());
		gc.setOpen(false);

		// 自定义文件命名，注意 %s 会自动填充表实体属性！
		gc.setEntityName(model.getClassName() + GenFileNameSuffix.ENTITY);
		gc.setMapperName(model.getClassName() + GenFileNameSuffix.MAPPER);
		gc.setXmlName(model.getClassName() + GenFileNameSuffix.MAPPER_XML);
		gc.setServiceName(model.getClassName() + GenFileNameSuffix.SERVICE);
		gc.setServiceImplName(model.getClassName() + GenFileNameSuffix.SERVICEIMPL);
		gc.setControllerName(model.getClassName() + GenFileNameSuffix.CONTROLLER);
		mpg.setGlobalConfig(gc);

		// 数据源配置
		mpg.setDataSource(SourceUtil.dbConfig(userInfo.getTenantDbConnectionString(), linkEntity));

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setEntityLombokModel(true);
		// 表名生成策略
		strategy.setNaming(NamingStrategy.underline_to_camel);
		// 需要生成的表
		strategy.setInclude(tableName);
		strategy.setRestControllerStyle(true);
		mpg.setStrategy(strategy);

		// 包配置
		PackageConfig pc = new PackageConfig();
		pc.setParent(GenBaseInfo.PACKAGE_NAME+"."+downloadCodeForm.getModule());
		mpg.setPackageInfo(pc);


		// 自定义配置
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
				// to do nothing
			}
		};
		List<FileOutConfig> focList = new ArrayList<>();
		String javaPath = model.getServiceDirectory();
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Controller.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "java" + File.separator + "controller" + File.separator + tableInfo.getControllerName() + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Entity.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				List<TableField> fieldAll = tableInfo.getFields();
				TableField mainTableField = fieldAll.stream().filter(tableField -> tableField.isKeyFlag()).findFirst().orElse(null);
				fieldAll=fieldAll.stream().filter(DataControlUtils.distinctByKey(t->t.getName())).collect(Collectors.toList());
				if(mainTableField != null){
					fieldAll.stream().filter(tableField -> tableField.getName().equals(mainTableField.getName())).forEach(t->t.setKeyFlag(mainTableField.isKeyFlag()));
				}
				for (TableField field : fieldAll) {
					String name = field.getName().toLowerCase().replaceAll("f_", "");
					field.setPropertyName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name));
				}
				tableInfo.setFields(fieldAll);
				return javaPath + fileName + File.separator + "java" + File.separator + "entity" + File.separator + tableInfo.getEntityName() + StringPool.DOT_JAVA;
			}
		});

		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Mapper.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "java" + File.separator + "mapper" + File.separator + tableInfo.getMapperName() + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Mapper.xml.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "resources" + File.separator + "mapper" + File.separator + tableInfo.getMapperName() + StringPool.DOT_XML;
			}
		});
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Service.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "java" + File.separator + "service" + File.separator + tableInfo.getServiceName() + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "ServiceImpl.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "java" + File.separator + "service" + File.separator + "impl" + File.separator + tableInfo.getServiceImplName() + StringPool.DOT_JAVA;
			}
		});
		cfg.setFileOutConfigList(focList);
		mpg.setTemplate(new TemplateConfig().setXml(null).setMapper(null).setController(null).setEntity(null).setService(null).setServiceImpl(null));
		mpg.setCfg(cfg);
		// 执行生成
		mpg.execute(path);
	}

	/**
	 * 生成子表
	 *
	 * @param modelName       模块
	 * @param path            路径
	 * @param fileName        文件夹名称
	 * @param className       文件名称
	 * @param table           子表
	 * @param userInfo        用户
	 * @param configValueUtil 下载路径
	 */
	private static void childTable(String path, String fileName, String templatePath, String modelName, String className, String table, UserInfo userInfo, ConfigValueUtil configValueUtil, DbLinkEntity linkEntity) {
		Map<String, Object> columndata = new HashMap<>(16);

		Template7Model model = new Template7Model();
		model.setClassName(table);
		model.setServiceDirectory(configValueUtil.getServiceDirectoryPath());
		model.setCreateDate(DateUtil.daFormat(new Date()));
		model.setCreateUser(GenBaseInfo.AUTHOR);
		model.setCopyright(GenBaseInfo.COPYRIGHT);
		model.setDescription(table);

		//数据源
		if (ObjectUtil.isNotEmpty(linkEntity)){
			columndata.put("DS",linkEntity.getFullName());
		}
		columndata.put("genInfo", model);
		CustomGenerator mpg = new CustomGenerator(columndata);
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setFileOverride(true);
		// 不需要ActiveRecord特性的请改为false
		gc.setActiveRecord(false);
		// XML 二级缓存
		gc.setEnableCache(false);
		// XML ResultMap
		gc.setBaseResultMap(false);
		// XML columList
		gc.setBaseColumnList(false);
		gc.setAuthor(model.getCreateUser());
		gc.setOpen(false);

		// 自定义文件命名，注意 %s 会自动填充表实体属性！
		gc.setEntityName(className + GenFileNameSuffix.ENTITY);
		gc.setMapperName(className + GenFileNameSuffix.MAPPER);
		gc.setXmlName(className + GenFileNameSuffix.MAPPER_XML);
		gc.setServiceName(className + GenFileNameSuffix.SERVICE);
		gc.setServiceImplName(className + GenFileNameSuffix.SERVICEIMPL);
		mpg.setGlobalConfig(gc);

		// 数据源配置
		mpg.setDataSource(SourceUtil.dbConfig(userInfo.getTenantDbConnectionString(), linkEntity));

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setEntityLombokModel(true);
		// 表名生成策略
		strategy.setNaming(NamingStrategy.underline_to_camel);
		// 需要生成的表
		strategy.setInclude(table);
		strategy.setRestControllerStyle(true);
		mpg.setStrategy(strategy);

		// 包配置
		PackageConfig pc = new PackageConfig();

		pc.setParent(GenBaseInfo.PACKAGE_NAME);
		mpg.setPackageInfo(pc);

		// 自定义配置
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
				// to do nothing
			}
		};
		List<FileOutConfig> focList = new ArrayList<>();
		String javaPath = model.getServiceDirectory();
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Entity.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				List<TableField> fieldAll = tableInfo.getFields();
				TableField mainTableField = fieldAll.stream().filter(tableField -> tableField.isKeyFlag()).findFirst().orElse(null);
				fieldAll=fieldAll.stream().filter(DataControlUtils.distinctByKey(t->t.getName())).collect(Collectors.toList());
				if(mainTableField != null){
					fieldAll.stream().filter(tableField -> tableField.getName().equals(mainTableField.getName())).forEach(t->t.setKeyFlag(mainTableField.isKeyFlag()));
				}
				for (TableField field : fieldAll) {
					String name = field.getName().toLowerCase().replaceAll("f_", "");
					field.setPropertyName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name));
				}
				tableInfo.setFields(fieldAll);
				return javaPath + fileName + File.separator + "java" + File.separator + "entity" + File.separator + tableInfo.getEntityName() + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Mapper.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "java" + File.separator + "mapper" + File.separator + tableInfo.getMapperName() + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Mapper.xml.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "resources" + File.separator + "mapper" + File.separator + tableInfo.getMapperName() + StringPool.DOT_XML;
			}
		});
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "Service.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "java" + File.separator + "service" + File.separator + tableInfo.getServiceName() + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig(templatePath + File.separator + "java" + File.separator + "ServiceImpl.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return javaPath + fileName + File.separator + "java" + File.separator + "service" + File.separator + "impl" + File.separator + tableInfo.getServiceImplName() + StringPool.DOT_JAVA;
			}
		});
		cfg.setFileOutConfigList(focList);
		mpg.setTemplate(new TemplateConfig().setXml(null).setMapper(null).setController(null).setEntity(null).setService(null).setServiceImpl(null));
		mpg.setCfg(cfg);
		// 执行生成
		mpg.execute(path);
	}

	/**
	 * 生成表集合
	 *
	 * @param entity           实体
	 * @param dataSourceModel   数据源
	 * @param fileName         文件夹名称
	 * @param downloadCodeForm 文件名称
	 * @param userInfo         用户
	 * @param configValueUtil  下载路径
	 */
	@Override
	public  void generate(VisualdevEntity entity, DataSourceModel dataSourceModel, String fileName, String templatePath, DownloadCodeForm downloadCodeForm, UserInfo userInfo, ConfigValueUtil configValueUtil, DbLinkEntity linkEntity) throws SQLException {
		List<TableModel> list = JsonUtil.getJsonToList(entity.getVisualTables(), TableModel.class);
		//生成代码
		int i = 0;
		for (TableModel model : list) {
			if ("1".equals(model.getTypeId())) {
				setCode(configValueUtil.getTemplateCodePath(), fileName, templatePath, downloadCodeForm, entity, userInfo, configValueUtil, linkEntity);
			} else if ("0".equals(model.getTypeId())) {
				String name = downloadCodeForm.getSubClassName().split(",")[i];
				String className = DataControlUtils.captureName(name);
				childTable(configValueUtil.getTemplateCodePath(), fileName, templatePath, downloadCodeForm.getModule(), className, model.getTable(), userInfo, configValueUtil, linkEntity);
				i++;
			}
		}
	}

}
